use clap::{Parser, Subcommand, ValueEnum};
use std::path::PathBuf;


mod shell;
mod output;
mod ssl;

use shell::{BinaryVersionCmd, ShellCmd};
use output::{Link};

#[derive(Parser, Debug)]
#[command(name = "tcssl", author, version, about, long_about = None)] // Read from `Cargo.toml`
struct Cli {
  /// Sets a custom config file
  #[arg(short, long, value_name = "FILE")]
  config: Option<PathBuf>,

  #[command(subcommand)]
  command: Commands,
}



// tcssl check
// tcssl check [tccli|acme|all]
// tcssl sync --domain www.biling.club
pub fn init_app() {
  let config = Cli::parse();
  println!("config => {:?}", config);
  match config.command {
    Commands::Check {
      prequire
    } => {
      
      let pass = check_prequires(&prequire);
      if !pass {
        
        eprintln!("checking prequire<{:?}> failed ", prequire);
        // let link = Link::new("DuckDuckGo", "https://duckduckgo.com");
        // eprintln!("{}", link.to_string());
      }
    },
    Commands::Sync { domain , ecc} => {
      let prequire = Prequires::All;
      let pass = check_prequires(&prequire);
      if !pass {
        eprintln!("checking prequire<{:?}> failed ", prequire);
        return;
      }
      println!("domain=>{domain}, ecc=>{ecc}", domain = &domain, ecc = ecc);
      let algorithm = if ecc {
        ssl::SslAlgorithm::ECDSA
      } else {
        ssl::SslAlgorithm::RSA
      };
      let adapter = ssl::AcmeSslAdapter::new(algorithm, &*domain);
      if !adapter.validate() {
        eprintln!("acme 无法找到域名,请确认该域名已经使用了acme生成ssl!");
      } else {
        match adapter.sync_to_tc()  {
          Ok(_) => {
            println!("域名<{}>已成功同步到tc", domain);
          },
          Err(err) => {
            eprintln!("域名<{}>同步失败,detail:{}", domain, err);
          }
        }
      }
    }
  }
}

fn check_prequires(prequire: &Prequires) -> bool {
  let pass = match prequire {
    Prequires::Tccli => {
      CMD_CHECK_TCCLI.exec()
    },
    Prequires::Acme => {
      CMD_CHECK_ACME.exec()
    },
    _ => {
      CMD_CHECK_TCCLI.exec()
      &&
      CMD_CHECK_ACME.exec()
    }
  };

  pass
}

#[derive(Debug, Subcommand)]
enum Commands {
  Check {
    #[arg( 
      require_equals = true,
      default_value_t = Prequires::All,
      default_missing_value = "all",
      value_enum
    )]
    prequire: Prequires,
  },
  Sync {
    #[arg( 
      short,
      long,
      required = true,
    )]
    domain: String,
    #[arg(
      long,
    )]   
    ecc: bool,
  }
}



#[derive(ValueEnum, Copy, Clone, Debug, PartialEq, Eq)]
enum Prequires {
  Tccli,
  Acme,
  All,
}
const TCCLI_BIN: &str = "tccli";
const ACME_HOME: &str = "~/.acme.sh";
const ACME_BIN: &str = const_format::concatcp!(ACME_HOME, "/acme.sh");

static CMD_CHECK_TCCLI:BinaryVersionCmd = BinaryVersionCmd::new(TCCLI_BIN, "--version", Some(Link::new("安装 TCCLI", "https://cloud.tencent.com/document/product/440/34011")));
static CMD_CHECK_ACME:ShellCmd = ShellCmd::new(ACME_BIN, Some(Link::new("安装 ACME", "https://github.com/acmesh-official/acme.sh")), "not install acme!");
